package cn.sq.musicserver.user.controller;


import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.sq.musicserver.config.ResponseBean;
import cn.sq.musicserver.config.StatusCode;
import cn.sq.musicserver.config.base.BaseController;
import cn.sq.musicserver.config.shiro.jwt.JWTUtil;
import cn.sq.musicserver.music.entity.SqMusic;
import cn.sq.musicserver.user.entity.SqUser;
import cn.sq.musicserver.user.service.ISqUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author SQ
 * @since 2020-12-30
 */
@RestController
@RequestMapping("/user")
@Api(value = "用户", tags = {"用户"})
public class SqUserController extends BaseController<SqUser, ISqUserService> {

    @ApiOperation(value = "登录")
    @ApiOperationSupport(params = @DynamicParameters(name = "参考对象(SqMusic)", properties = {
            @DynamicParameter(name = "email", value = "邮箱账号", example = "59799517@qq.com", required = true, dataTypeClass = MultipartFile.class),
            @DynamicParameter(name = "password", value = "密码", example = "123", required = true, dataTypeClass = SqMusic.class),
    }))
    @RequestMapping("/login")
    public ResponseBean login(@RequestBody Map<String, String> map) {
        String email = map.get("email");
        String password = map.get("password");
        //登录成功
        SqUser login = super.getsService().getOne(new QueryWrapper<SqUser>().eq("UserEmail", email));
        if (login != null) {
            String s = SecureUtil.sha256(password + login.getUsersalt());
            if (s.equals(login.getUserPassword())) {
                String sign = JWTUtil.sign(email, login.getUserPassword(), "email");
                login.setUserPassword(sign);
                return StatusCode.successResponseBean(login);
            }
            throw new UnauthorizedException();

        } else {
            throw new UnauthorizedException();
        }
    }

    @ApiOperation(value = "注册账号")
    @RequestMapping("/register")
    @ApiOperationSupport(params = @DynamicParameters(name = "参考对象(SqMusic)", properties = {
            @DynamicParameter(name = "email", value = "邮箱账号", example = "59799517@qq.com", required = true, dataTypeClass = MultipartFile.class),
            @DynamicParameter(name = "password", value = "密码", example = "123", required = true, dataTypeClass = SqMusic.class),
            @DynamicParameter(name = "name", value = "名称", example = "名称", required = true, dataTypeClass = SqMusic.class),
    }))
    public ResponseBean register(@RequestBody Map<String, String> map) {
        String email = map.get("email");
        int userEmail = super.getsService().count(new QueryWrapper<SqUser>().eq("UserEmail", email));
        if (userEmail > 0) {
            StatusCode.successResponseBean(false, "邮箱有重复的");
        }
        String password = map.get("password");
        String name = map.get("name");
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String salt = md5.digestHex(email + "/" + password + "/" + UUID.randomUUID().toString(true));
        SqUser sqUser = new SqUser().setUserEmail(email).setUserName(name).setUserPassword(SecureUtil.sha256(password + salt)).setUsersalt(salt).setLocked("0");
        return StatusCode.successResponseBean(super.add(sqUser));
    }

    @ApiOperation(value = "修改密码")
    @RequestMapping("/changePassword")
    @ApiOperationSupport(params = @DynamicParameters(name = "参考对象(SqMusic)", properties = {
            @DynamicParameter(name = "email", value = "邮箱账号", example = "59799517@qq.com", required = true, dataTypeClass = MultipartFile.class),
            @DynamicParameter(name = "password", value = "密码", example = "123", required = true, dataTypeClass = SqMusic.class),
            @DynamicParameter(name = "newpassword", value = "新密码", example = "111111", required = true, dataTypeClass = SqMusic.class),
    }))
    public ResponseBean changePassword(@RequestBody Map<String, String> map) {
        String email = map.get("email");
        String password = map.get("password");
        String newpassword = map.get("newpassword");
        SqUser login = super.getsService().getOne(new QueryWrapper<SqUser>().eq("UserEmail", email));
        if (login != null) {
            String s = SecureUtil.sha256(password + login.getUsersalt());
            if (s.equals(login.getUserPassword())) {
                Digester md5 = new Digester(DigestAlgorithm.MD5);
                String salt = md5.digestHex(email + "/" + newpassword + "/" + UUID.randomUUID().toString(true));
                SqUser sqUser = login.setUserPassword(SecureUtil.sha256(newpassword + salt)).setUsersalt(salt);
                if (super.update(sqUser)) {
                    return StatusCode.successResponseBean();
                }
                return StatusCode.R_Error;
            }
            return StatusCode.R_ERROR_LOGIN_PASSWORD;

        } else {
            return StatusCode.R_ERROR_LOGIN_USERNAME;
        }

    }

    @RequiresRoles(value = {"admin"})
    @ApiOperation(value = "管理员修改密码")
    @RequestMapping("/adminChangePassword")
    @ApiOperationSupport(params = @DynamicParameters(name = "参考对象(SqMusic)", properties = {
            @DynamicParameter(name = "email", value = "邮箱账号", example = "59799517@qq.com", required = true, dataTypeClass = MultipartFile.class),
            @DynamicParameter(name = "newpassword", value = "新密码", example = "111111", required = true, dataTypeClass = SqMusic.class),
    }))
    @RequiresPermissions(value={"admin:changepassword"})
    public ResponseBean adminChangePassword(@RequestBody Map<String, String> map) {
        String email = map.get("email");
        String newpassword = map.get("newpassword");
        SqUser login = super.getsService().getOne(new QueryWrapper<SqUser>().eq("UserEmail", email));
        if (login != null) {
            Digester md5 = new Digester(DigestAlgorithm.MD5);
            String salt = md5.digestHex(email + "/" + newpassword + "/" + UUID.randomUUID().toString(true));
            SqUser sqUser = login.setUserPassword(SecureUtil.sha256(newpassword + salt)).setUsersalt(salt);
            if (super.update(sqUser)) {
                return StatusCode.successResponseBean();
            }
            return StatusCode.R_Error;
        } else {
            return StatusCode.R_ERROR_LOGIN_USERNAME;
        }

    }
    @ApiOperation(value = "检查token有效性并刷新")
    @RequestMapping("/verifyToken")
    @ApiOperationSupport(params = @DynamicParameters(name = "参考对象(SqMusic)", properties = {
            @DynamicParameter(name = "token", value = "token值", example = "", required = true, dataTypeClass = MultipartFile.class),
            @DynamicParameter(name = "newpassword", value = "新密码", example = "111111", required = true, dataTypeClass = SqMusic.class),
    }))
    public  ResponseBean verifyToken(@RequestBody Map<String, String> map){
        try {
            String email = JWTUtil.getUsername(map.get("token"),"email");
            String password = JWTUtil.getUsername(map.get("token"),"secret");
            boolean verify = JWTUtil.verify(map.get("token"), email, password, "email");
            if (verify){
                return StatusCode.successResponseBean(JWTUtil.sign(email, password, "email"));
            }
            return StatusCode.R_Error_TOKEN;
        } catch (Exception e) {
            return StatusCode.R_Error_TOKEN;

        }

    }


}
